package team.nmsg.ge.system.service.impl;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.Cache;
import org.springframework.cache.Cache.ValueWrapper;
import org.springframework.cache.ehcache.EhCacheCacheManager;
import org.springframework.stereotype.Service;

import team.nmsg.ge.system.AppServerConstant;
import team.nmsg.ge.system.bean.AppToken;
import team.nmsg.ge.system.service.ICacheService;
import team.nmsg.ge.system.util.SysSpringContext;
import net.sf.ehcache.Element;

@Service
public class EhCacheServiceImpl implements ICacheService {

	private static final Logger logger = LoggerFactory.getLogger(EhCacheServiceImpl.class);
	private ICacheService proxyObject;
	private ICacheService getProxyCacheService() {
		return proxyObject == null ? SysSpringContext.getService(ICacheService.class) : proxyObject;
	}

	@Autowired
	private EhCacheCacheManager cacheManager = null;

	public boolean addTokenToCahce(AppToken tokenObj) {

		Cache cache = cacheManager.getCache(AppServerConstant.NMS_TOKEN_CACHE);
		
		try {
			AppToken lastToken = (AppToken)(cache.get(tokenObj.getUserName()).get());
			if(lastToken != null){
				getProxyCacheService().removeTokenFromCahce(lastToken);
			}
		} catch (Exception e) {
			logger.error(e.getMessage());
		}
		
		String tokenKey = tokenObj.getToken();
		cache.put(tokenKey, tokenObj);
		cache.put(tokenObj.getUserName(), tokenObj);

		return true;
	}

	public boolean removeTokenFromCahce(AppToken tokenObj) {

		Cache cache = cacheManager.getCache(AppServerConstant.NMS_TOKEN_CACHE);

		String tokenKey = tokenObj.getToken();
		cache.evict(tokenKey);
		cache.evict(tokenObj.getUserName());//
		return true;
	}

	public AppToken getTokenFromCache(AppToken tokenObj) {

		Cache cache = cacheManager.getCache(AppServerConstant.NMS_TOKEN_CACHE);
		String tokenKey = tokenObj.getToken();

		ValueWrapper valueWrapper = cache.get(tokenKey);
		if (valueWrapper != null) {
			Object object = valueWrapper.get();
			if (object != null && object instanceof AppToken) {
				return (AppToken) object;
			}
		}

		return null;
	}

	public boolean updTokenFromCahce(AppToken tokenObj) {

		Cache cache = cacheManager.getCache(AppServerConstant.NMS_TOKEN_CACHE);
		String tokenKey = tokenObj.getToken();

		cache.put(tokenKey, tokenObj);

		return true;
	}

	@Override
	public List<AppToken> getAllTokenFromCache() {
		List<AppToken> retList = new ArrayList<AppToken>();
		Cache cache = null;
		try {
			cache = cacheManager.getCache(AppServerConstant.NMS_TOKEN_CACHE);
			Object nativeCache = cache.getNativeCache();
			if(nativeCache instanceof net.sf.ehcache.Cache){
				net.sf.ehcache.Cache abc = (net.sf.ehcache.Cache) nativeCache;
				Map<Object, Element> allCache = abc.getAll(abc.getKeys());
				Set<Entry<Object, Element>> entrySet = allCache.entrySet();
				for (Entry<Object, Element> entry : entrySet) {
					Element value = entry.getValue();
					AppToken token = (AppToken) value.getValue();
					retList.add(token);
				}
			}
		} catch (Exception e) {
			logger.error("", e);
		}
		return retList;
	}

}
